package net.m2technologies.open_arm.utilities.generic_object_functions;

import java.lang.reflect.Field;

/**
 * Copyright 2005 Mark Masterson<br> <br> Licensed under the Apache License, Version 2.0 (the "License");<br> you may
 * not use this file except in compliance with the License.<br> You may obtain a copy of the License at<br> <br>
 * http://www.apache.org/licenses/LICENSE-2.0<br> <br> Unless required by applicable law or agreed to in writing,
 * software<br> distributed under the License is distributed on an "AS IS" BASIS,<br> WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, either express or implied.<br> See the License for the specific language governing permissions and<br>
 * limitations under the License.<br>
 * <p/>
 * <p>Description: </p>
 *
 * @author Mark Masterson
 * @version 0.010
 */
class ToStringWorker extends ReflectiveWorker {

    static final char TO_STRING_TERM_SEPARATOR = '|';
    static final char TO_STRING_EQUALS_CHARACTER = '=';

    private String toStringRecursiveResult = "";

    public String toString(final Object object) {
        if (null == object) return "";
        if (!"".equals(this.toStringRecursiveResult)) {
            this.toStringRecursiveResult = "";
        }
        final Class clazz = object.getClass();
        final StringBuffer result = new StringBuffer().append(clazz.getName()).append(TO_STRING_TERM_SEPARATOR);
        try {
            final Object[] tempArray = isObjectArray(object);
            if (null != tempArray) {
                result.append(toStringBuffer(tempArray));
            } else {
                final Field[] fields = getAccessibleFields(clazz);
                for (int i = 0; i < fields.length; i++) {
                    final Field field = fields[i];
                    result.append(field.getName()).append(TO_STRING_EQUALS_CHARACTER);
                    result.append(getFieldValueAsString(field, object));
                    if (i < fields.length - 1) result.append(TO_STRING_TERM_SEPARATOR);
                }
            }
        } catch (SecurityException ex) {
            throw new RuntimeException(ex);
        }
        final Class superClazz = clazz.getSuperclass();
        if (superClazz != clazz && !superClazz.equals(Object.class)) {
            result.append(toStringRecursive(superClazz, object));
        }
        return result.toString();
    }

    private String toStringRecursive(final Class clazz, final Object object) {
        final StringBuffer tempBuffer = new StringBuffer();
        tempBuffer.append(TO_STRING_TERM_SEPARATOR).append(clazz.getName()).append(TO_STRING_TERM_SEPARATOR);
        try {
            final Field[] fields = getAccessibleFields(clazz);
            for (int i = 0; i < fields.length; i++) {
                final Field field = fields[i];
                tempBuffer.append(field.getName()).append(TO_STRING_EQUALS_CHARACTER);
                tempBuffer.append(getFieldValueAsString(field, object)).append(TO_STRING_TERM_SEPARATOR);
            }
        } catch (SecurityException ex) {
            throw new RuntimeException(ex);
        } catch (StackOverflowError er) {
            return this.toStringRecursiveResult;
        }
        final Class superClazz = clazz.getSuperclass();
        if (superClazz != clazz
            && !superClazz.equals(Object.class)) {
            tempBuffer.append(toStringRecursive(superClazz, object));
        }
        this.toStringRecursiveResult = tempBuffer.toString();
        return this.toStringRecursiveResult;
    }

}
